import calendar
import datetime
import time

import pandas as pd
import numpy as np

def secs2str(secs):
    return time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(secs))

def getToday():
    today = datetime.date.today()
    return str(today)

def getBeforeday(nday):
    today = datetime.date.today()
    difday = datetime.timedelta(days=nday)
    beforeday = today-difday
    return str(beforeday)

def getAfterday(curdateStr, nday):
    curdate = datetime.datetime.strptime(curdateStr, "%Y-%m-%d")
    difday = datetime.timedelta(days=nday)
    afterday = (curdate+difday).date()
    return str(afterday)

def interval_timesec(date1, date2):
    return (date1 - date2).seconds

'''
(北京时间)
夏令时 4-11月
持续交易时段-21:30pm~4:00am   盘前时间-4:00pm~9:30pm  盘后时间-4:00am~8:00am
冬令时 11-4月
持续交易时段-22:30pm~5:00am   盘前时间-5:00pm~10:30pm  盘后时间-5:00am~9:00am
'''
# 计算出今年的夏令时范围
def summerTime(now=None):
    if now == None:
        now = datetime.datetime.now()
    elif type(now) == str:
        now = datetime.datetime.strptime(now, '%Y-%m-%d')

    endDate = range(calendar.monthrange(now.year, 3)[1] + 1)[-1]
    month3_dateList = pd.date_range(start=f'{now.year}-03-01', end=f'{now.year}-03-{str(endDate)}')
    month3_dateList = list([x.date() for x in month3_dateList])
    weekList = [x.weekday() for x in month3_dateList]
    sd = month3_dateList[[i for i, x in enumerate(weekList) if x == 6][1]]  # 第二个星期日的索引

    endDate = range(calendar.monthrange(now.year, 11)[1] + 1)[-1]
    month11_dateList = pd.date_range(start=f'{now.year}-11-01', end=f'{now.year}-11-{str(endDate)}')
    month11_dateList = list([x.date() for x in month11_dateList])
    weekList = [x.weekday() for x in month11_dateList]
    ed = month11_dateList[[i for i, x in enumerate(weekList) if x == 6][0]]  # 第一个星期日的索引

    return str(sd), str(ed)

def leftMove(dlist, one):
    move_dl = dlist[1:]
    move_dl.append(one)
    return move_dl

def get_follow_code_us():
    followStocks = [['US.TSLA',],
                    ['US.AAPL',]]
    return followStocks

def get_price_limit():
    plimit_config = [
        {'class': "一级", 'change_rate_u': 0.5, 'min_u': 10, 'change_rate_d': -0.5, 'min_d': 10},
        {'class': "二级", 'change_rate_u': 0.5, 'min_u': 20, 'change_rate_d': -0.5, 'min_d': 20},
        {'class': "三级", 'change_rate_u': 0.5, 'min_u': 30, 'change_rate_d': -0.5, 'min_d': 30},
        {'class': "四级", 'change_rate_u': 0.5, 'min_u': 60, 'change_rate_d': -0.5, 'min_d': 60},
        {'class': "五级", 'change_rate_u': 0.5, 'min_u': 120, 'change_rate_d': -0.5, 'min_d': 120}
    ]
    return plimit_config

def get_follow_code():
    followStock = [get_follow_codes()[0]]
    return followStock

def process_data(data):
    if data['code'].startswith('US.'):
        if data['data_time'] == '16:00:00' or data['data_time'] == '17:00:00':  # 美股盘中与盘前盘后判断
            now_time = str(datetime.datetime.now().time())[:8]
            if '16:00:00' <= now_time <= '22:30:00':  # 盘前（夏冬令时）
                data['data_time'] = now_time
                data['last_price'] = data['pre_price']
            elif data['data_time'] == '16:00:00' and now_time >= '04:00:01':  # 夏令时盘后
                data['data_time'] = now_time
                data['last_price'] = data['after_price']
            elif data['data_time'] == '17:00:00' and now_time >= '05:00:01':  # 冬令时盘后
                data['data_time'] = now_time
                data['last_price'] = data['after_price']
            else:
                pass
        else:
            datatStr = data['data_time'][:8]
            data['data_time'] = datatStr

    return data

def getShortOptionDetail(taskid):
    shortOptionDetail = {'from_name': ['forecast_ud'],
                         'o_name': ['苹果短线20210819'],
                         'code': ['US.AAPL'],
                         'date_range': ['2021-08-16 - 2021-08-18'],
                         'time_range': ['09:30:00 - 10:30:00'],
                         'money_way_new': ['cash_way'],
                         'freight_space': ['freight_space_way'],
                         'number_price': ['stockNumber'],
                         'stockNumber_money': ['15'],
                         'ifcontinue': ['0'],
                         'change_price': ['first_change_price'],
                         'pre': ['on'],
                         'middle': ['on'],
                         # 'after': ['on'],
                         'closeDate': ['2021-07-06'],
                         'closeTime': ['16:00'],
                         'f_time': ['on'],
                         'open_price': ['6.29'],
                         'options_name': [''],
                         'money': ['95.25'],
                         'stock_numbers': ['15'],
                         'token': ['1625537622AIBinAI-b9X2aAg'],
                         'TrdEnv': ['SIMULATE'],
                         'stock_name': ['好未来'],
                         'buyPrice': ['6.35'],
                         'sellPrice': ['6.35'],
                         'fmopenTime': [datetime.datetime(2021, 7, 6, 16, 0)],
                         'fmcloseTime': [datetime.datetime(2021, 8, 12, 8, 0)],
                         'buyItemList': [
                             '[{"aItem": "正股,当前市价", "bItem": "指定价格", "cItem": "小于等于", "dItem": "未定义", "searchStock_two2": "", "eItem": "未定义", "itemValue": "6.35", "label_value": "数值:"}]'],
                         'sellItemList': [
                             '[{"aItem": "正股,单次盈亏", "bItem": "幅度", "cItem": "盈利", "dItem": "未定义", "eItem": "未定义", "itemValue": "1.9", "label_value": "数值:"}]'],
                         'stopItemList': [
                             '[{"aItem": "正股,时间", "bItem": "未定义", "searchStock": "", "volumeValue": "", "itemValue_2": "", "cItem": "开盘过去时间", "dItem": "未定义", "searchStock_two2": "", "eItem": "未定义", "itemValue": "11:55:00", "itemValueDay": "11:55:00", "itemValue_day": "", "label_value": "数值:"}]']
                         }
    return shortOptionDetail

def process_sna_data2(data, summer_sd, summer_ed, today, dict_gb, MORNING=False):
    now_time = str(datetime.datetime.now().time())[:8]
    if 'US.' in data['code']:
        if summer_sd <= today < summer_ed:  # 夏令时
            middle_end_time = '04:00:00' if MORNING == False else '01:00:00'  # 夏令时盘中收盘时间，如果是节假日提前休市3小时
            if '16:00:00' <= now_time <= '21:30:00':  # 夏令时盘前
                # data = data[['code', 'data_date', 'data_time', 'pre_price', 'pre_change_val', 'pre_change_rate',
                #              'pre_volume', 'pre_turnover', 'pre_high_price', 'pre_low_price']]
                data['last_price'] = data['pre_price']
                data['high_price'] = data['pre_high_price']
                data['low_price'] = data['pre_low_price']
                data['volume'] = data['pre_volume']
                data['turnover'] = data['pre_turnover']
                data['change'] = data['pre_change_val']
                data['change_rate'] = data['pre_change_rate']

                # data.rename(
                #     columns={'pre_price': 'last_price', 'pre_high_price': 'high_price','pre_low_price': 'low_price',
                #              'pre_volume': 'volume', 'pre_turnover': 'turnover', 'pre_change_val': 'change',
                #              'pre_change_rate': 'change_rate'}, inplace=True)
                data['data_time'] = str(datetime.datetime.now().time())[:8]
                data['dt'] = str(datetime.datetime.now())[:19]
                if len(data['code']) > 10:  # 期权盘前成交额没有
                    data['turnover'] = 0

            elif '21:30:00' <= now_time <= '23:59:59' or '00:00:00' <= now_time < middle_end_time:  # 夏令时盘中
                # data = data[['code', 'data_date','data_time', 'last_price', 'volume', 'turnover', 'high_price', 'low_price',
                #              'prev_close_price']]
                data['change'] = round(data['last_price'] - data['prev_close_price'], 3)
                data['change_rate'] = round(data['change'] / data['prev_close_price'] * 100, 2) if data['change']!=0 else 0
                data['dt'] = str((datetime.datetime.strptime(data['data_date']+' '+data['data_time'][:8], '%Y-%m-%d %H:%M:%S'))+datetime.timedelta(hours=12))[:19]
            else:  # 夏令时盘后
                # 在盘后的第一秒跳过
                if '04:00:00'<=now_time<='04:00:01':
                    return None

                # data = data[['code', 'data_date', 'data_time', 'after_price', 'after_change_val', 'after_change_rate',
                #      'after_volume', 'after_turnover', 'after_high_price', 'after_low_price']]
                data['last_price'] = data['after_price']
                data['high_price'] = data['after_high_price']
                data['low_price'] = data['after_low_price']
                data['volume'] = data['after_volume']
                data['turnover'] = data['after_turnover']
                data['change'] = data['after_change_val']
                data['change_rate'] = data['after_change_rate']

                # data.rename(
                #     columns={'after_price': 'last_price', 'after_high_price': 'high_price',
                #              'after_low_price': 'low_price',
                #              'after_volume': 'volume', 'after_turnover': 'turnover', 'after_change_val': 'change',
                #              'after_change_rate': 'change_rate'}, inplace=True)
                data['data_time'] = str(datetime.datetime.now().time())[:8]
                data['dt'] = str(datetime.datetime.now())[:19]
                if len(data['code']) > 10:  # 期权盘前成交额没有
                    data['turnover'] = 0
        else:  # 冬令时
            middle_end_time = '05:00:00' if MORNING==False else '02:00:00' # 冬令时盘中收盘时间，如果是节假日提前休市3小时
            if '17:00:00' <= now_time <= '22:30:00':  # 冬令时盘前  【右边界是否用等于号】
                # data = data[['code', 'data_date', 'data_time', 'pre_price', 'pre_change_val', 'pre_change_rate',
                #              'pre_volume', 'pre_turnover', 'pre_high_price', 'pre_low_price']]
                data['last_price'] = data['pre_price']
                data['high_price'] = data['pre_high_price']
                data['low_price'] = data['pre_low_price']
                data['volume'] = data['pre_volume']
                data['turnover'] = data['pre_turnover']
                data['change'] = data['pre_change_val']
                data['change_rate'] = data['pre_change_rate']

                # data.rename(
                #     columns={'pre_price': 'last_price', 'pre_high_price': 'high_price',
                #              'pre_low_price': 'low_price',
                #              'pre_volume': 'volume', 'pre_turnover': 'turnover', 'pre_change_val': 'change',
                #              'pre_change_rate': 'change_rate'}, inplace=True)
                data['data_time'] = str(datetime.datetime.now().time())[:8]
                data['dt'] = str(datetime.datetime.now())[:19]
                if len(data['code']) > 10:
                    data['turnover'] = 0
            elif '22:30:00' <= now_time <= '23:59:59' or '00:00:00' <= now_time < middle_end_time:  # 冬令时盘中
                # data = data[['code', 'data_date', 'data_time', 'last_price', 'volume', 'turnover', 'high_price', 'low_price',
                #              'prev_close_price']]
                data['change'] = round(data['last_price'] - data['prev_close_price'],3)
                data['change_rate'] = round(data['change'] / data['prev_close_price'] * 100,2) if data['change']!=0 else 0
                data['dt'] = str((datetime.datetime.strptime(data['data_date']+' '+data['data_time'][:8], '%Y-%m-%d %H:%M:%S'))+datetime.timedelta(hours=13))[:19]
            else:  # 冬令时盘后
                # data = data[['code', 'data_date', 'data_time', 'after_price', 'after_change_val', 'after_change_rate',
                #      'after_volume', 'after_turnover', 'after_high_price', 'after_low_price']]
                data['last_price'] = data['after_price']
                data['high_price'] = data['after_high_price']
                data['low_price'] = data['after_low_price']
                data['volume'] = data['after_volume']
                data['turnover'] = data['after_turnover']
                data['change'] = data['after_change_val']
                data['change_rate'] = data['after_change_rate']

                # data.rename(
                #     columns={'after_price': 'last_price', 'after_high_price': 'high_price',
                #              'after_low_price': 'low_price',
                #              'after_volume': 'volume', 'after_turnover': 'turnover', 'after_change_val': 'change',
                #              'after_change_rate': 'change_rate'}, inplace=True)
                data['data_time'] = str(datetime.datetime.now().time())[:8]
                data['dt'] = str(datetime.datetime.now())[:19]
                if len(data['code']) > 10:
                    data['turnover'] = 0
    else:
        # data = data[['code', 'data_time', 'last_price', 'volume', 'turnover', 'high_price', 'low_price',
        #              'prev_close_price']]
        data['dt'] = data['data_date'] + ' ' + data['data_time'][:8]
        data['change'] = round(data['last_price'] - data['prev_close_price'],3)
        data['change_rate'] = round(data['change'] / data['prev_close_price'] * 100,2) if data['change']!=0 else 0

    if data['last_price'] == 'N/A':
        return None
    data['data_time'] = data['data_time'][:8]

    if len(data['code']) <= 10:
        data['market_val'] = round(data['last_price'] * data['dict_gb'], 2)  # 市值=市价*总股本
    else:
        data['market_val'] = 0
    data['prev_close_price'] = round(data['last_price'] - data['change'], 2)

    return data


def get_follow_codes():
    #followStocks = ['HK.00700']
    #followStocks = ['SZ.002555','SZ.002594','SZ.300222','SH.600030','SH.600519','SZ.000733','SZ.000858','SZ.300027','SZ.002602','SZ.000725','SZ.000001','SZ.000004','SZ.000009']
    #followStocks = ['HK.00700', 'HK.00011', 'HK.00012', 'HK.00013', 'HK.00016', 'HK.00017', 'HK.00018', 'HK.00019', 'HK.00021', 'HK.00022', 'HK.00023', 'HK.00024', 'HK.00025', 'HK.00026', 'HK.00027', 'HK.00028', 'HK.00029', 'HK.00030', 'HK.00031', 'HK.00032', 'HK.00033', 'HK.00034', 'HK.00035', 'HK.00036', 'HK.00037', 'HK.00038', 'HK.00039', 'HK.00040', 'HK.00041', 'HK.00042', 'HK.00043', 'HK.00045', 'HK.00046', 'HK.00047', 'HK.00048', 'HK.00050', 'HK.00051', 'HK.00052', 'HK.00053', 'HK.00055', 'HK.00057', 'HK.00058', 'HK.00059', 'HK.00060', 'HK.00061', 'HK.00062', 'HK.00063', 'HK.00064', 'HK.00065', 'HK.00066', 'HK.00067', 'HK.00068', 'HK.00069', 'HK.00070', 'HK.00071', 'HK.00072', 'HK.00073', 'HK.00075', 'HK.00076', 'HK.00077', 'HK.00078', 'HK.00079', 'HK.00080', 'HK.00081', 'HK.00082', 'HK.00083', 'HK.00084', 'HK.00085', 'HK.00086', 'HK.00087', 'HK.00088', 'HK.00089', 'HK.00090', 'HK.00091', 'HK.00092', 'HK.00093', 'HK.00094', 'HK.00095', 'HK.00096', 'HK.00097', 'HK.00098', 'HK.00099', 'HK.00100', 'HK.00101', 'HK.00102', 'HK.00103', 'HK.00104', 'HK.00105', 'HK.00106', 'HK.00107', 'HK.00108', 'HK.00109', 'HK.00110', 'HK.00111', 'HK.00112', 'HK.00113', 'HK.00115', 'HK.00116']

    followStocks = [
        'HK.00700',
        'HK.01024',
        'HK.06055',
        'HK.02318', # 中国平安
        'HK.00175', # 吉利汽车
        'HK.06862', # 海底捞
        'HK.01398',  # 工商银行
        'HK.00001',  # 长和
        'HK.02319',  # 蒙牛乳业
        'HK.00027',  # 银河娱乐
        'HK.03888',
        'HK.02400',
        'HK.02020',
        'HK.03690',
        'HK.00799',
        'HK.06820',
        'HK.01810',
        'HK.02013',
        'HK.09990',
        'HK.00285',
        'HK.00302',
        'HK.01585',
        'HK.00101',
        'HK.09633',
        'HK.00029',
        'HK.09988',
        'HK.00268',
        'HK.01211', # 比亚迪
        'HK.00354',
        'HK.00708',
        'HK.02331',
        'HK.00305',
        'HK.06183',
        'HK.01347',
        'HK.03968',
        'HK.06066',
        'HK.00998',
        'HK.02669',
        'HK.09868',
        'HK.01860',
        'US.TSLA',
        'US.BABA',
        'US.BIDU',
        'US.PDD',
        'US.BA',
        'US.NIO',
        'US.FUTU',
        'US.DAL',
        'US.QFIN',
        'US.DADA',
        'US.YY',
        'US.XPEV',
        'US.LI',
        'US.AAPL',
        'US.MOMO',
        'US.JD',
        'US.AMZN',
        'US.BYND',
        'US.EH',
        'US.GME',
        'US.NVDA',
        'US.EDU',
        'US.QCOM',
        'US.ZTCOY',
        'US.LKNCY',
        'US.LIZI',
        'US.MSFT',
        'US.FB',
        'US.DOYU',
        'US.HUYA',
        'US.JOBS',
        'US.BILI',
        'US.IQ',
        'US.BEKE',
        'US.KRKR',
        'US.SOHU',
        'US.BITA',
        'US.VIOT',
        'US.WB',
        'US.TCOM',
        'US.VIPS',
        'US.CMCM',
        'US.NTES',
        'US.UXIN',
        'US.TME',
        'US.TWTR',
        'US.GOOG',
        'US.SOGO',
        'US.TSM',
        'US.KO',
        'US.COST',
        'US.UBER',
        'US.SBUX',
        'US.PYPL',
        'US.MET',
        'US.NKE',
        'US.XNET',
        'US.AMC',
        'US.DNK',
        'US.EBAY',
        'US.AAL',
        'US.DAO',
        'US.SECO',
        'US.LAIX',
        'US.LFC',
        'US.KC',
        'US.AMD',
        'US.BB',
        'US.ZM',
        'US.YALA',
        'US.QH',
        'US.PSAC',
        'US.NVAX',
        'US.IBM',
        'US.NIU',
        'US.TIGR',
        'US.ADBE',
        'US.MNSO',
        'US.QTT',
        'US.INTC',
        'US.KXIN',
        'US.TAL',
        'US.TSP',
        'US.BZ',
        'US.RLX'
    ]

    return followStocks

# str转时间戳
def strTime_to_timestamp(strTime):
    if type(strTime)==str:
        return datetime.datetime.strptime(strTime, '%Y-%m-%d %H:%M:%S').timestamp()
    else:
        return strTime.timestamp()


# 获取有效期卖出时间
# trade_date_list下一年的没有更新
def get_vail_sellTime_2(buyTime,trade_date_list,ifSummer,stopItem,market='US'):

    if market=='US':
        # datetime.datetime(2021, 10, 13, 21, 35, 3)  # 北京买入
        # datetime.datetime(2021, 10, 13, 9, 35, 3)  # 美东买入
        # 3天有效期，人工转换 2021-10-15 15:55:00  # 美东卖出  -->  转回北京时间是2021-10-16 03:55:00

        # 03:55:00（北京时间的）， 要先单独减12时区转成美东的15:55:00
        #   冬令时的时候04:55:00（北京时间）,单独转成减13时区转成美东的15:55:00
        # 按美东交易日历，得到2021-10-15美东 + 15:55:00 转 北京时间
        if ifSummer:
            hours = 12
        else:
            hours = 13

        # 1.先买入时间由北京时间转成美东时间
        us_buyTime = buyTime + datetime.timedelta(hours=-hours)
        # 2.按美东交易日历得到卖出的美东日期
        buyDateIndex = trade_date_list.index(str(us_buyTime.date()))
        sellDate = trade_date_list[buyDateIndex + int(stopItem['bItem']) - 1]  # 用的美东时间要-1
        # 3.有效期时间03:55:00（北京时间的），要先单独减12时区转成美东的15:55:00
        vail_time = str((datetime.datetime.strptime(f'2020-01-02 {stopItem["itemValue"]}', '%Y-%m-%d %H:%M:%S')
                         + datetime.timedelta(hours=-hours)).time())[:8]
        # 4.组合时间再转回北京时间
        item_time = datetime.datetime.strptime(f'{sellDate} {vail_time}', '%Y-%m-%d %H:%M:%S') \
                    + datetime.timedelta(hours=hours)

        if item_time<=buyTime:
            return None

        return item_time
    else:
        print(buyTime)
        buyDateIndex = trade_date_list.index(str(buyTime.date()))
        sellDate = trade_date_list[buyDateIndex + int(stopItem['bItem']) - 1]  # 用的美东时间要-1
        item_time = datetime.datetime.strptime(f'{sellDate} {stopItem["itemValue"]}', '%Y-%m-%d %H:%M:%S')
        if item_time<=buyTime:
            return None

        return item_time


# 发邮箱
def sendEmail(subject,content):
    import smtplib
    from email.mime.text import MIMEText
    msg_from = '928398631@qq.com'  # 发送方邮箱
    passwd = 'wbntutrnbogpbfgd'  # 填入发送方邮箱的授权码
    msg_to = '928398631@qq.com'  # 收件人邮箱

    # subject = "ibgateway异常"  # 主题
    # content = "null"
    msg = MIMEText(content)
    msg['Subject'] = subject
    msg['From'] = msg_from
    msg['To'] = msg_to
    try:
        s = smtplib.SMTP_SSL("smtp.qq.com", 465)  # 邮件服务器及端口号
        s.login(msg_from, passwd)
        s.sendmail(msg_from, msg_to, msg.as_string())
        print("发送成功")
        s.quit()
    except Exception as e:
        print("发送失败" ,e)



def Except_stop(tbl_option,tbl_option_log,O_name,acc_id,error_msg,cursor,conn,now,main_sql=''):
    sql_tmp = f'UPDATE {tbl_option} set runState="手动暂停" where O_name="{O_name}" and acc_id="{acc_id}"' if main_sql=='' else main_sql
    cursor.execute(sql_tmp)
    insert_sql = f'insert into {tbl_option_log} (`O_name`,`logTime`,`logPrice`,`logStr`,`acc_id`) VALUES ("{O_name}","{strTime_to_timestamp(now)}","0","{error_msg}","{acc_id}");'
    cursor.execute(insert_sql)
    conn.commit()
    sendEmail('实盘异常自动暂停',f'{O_name} {acc_id} {error_msg}')



if __name__ == '__main__':
    print(getToday())
    print(summerTime())
    plimit_config = get_price_limit()
    kbarLen = [x['min_u'] for x in plimit_config]
    print(max(kbarLen))
